package com.cbgolf.oa.model;

import android.support.v4.util.ArrayMap;
import com.amap.api.maps.model.LatLng;
import com.cbgolf.oa.base.BaseModel;
import com.cbgolf.oa.contract.IParkMapContract.IParkMapModel;
import com.cbgolf.oa.entity.LatLon;
import com.cbgolf.oa.entity.ParkBean;
import com.cbgolf.oa.entity.ParkWayInfo;
import com.cbgolf.oa.event.EventPark;
import com.cbgolf.oa.manager.DataManager;
import com.cbgolf.oa.net.NetCallBack;
import com.cbgolf.oa.net.Web;
import com.cbgolf.oa.net.WebAPI;
import com.cbgolf.oa.util.CollectionUtil;
import com.cbgolf.oa.util.MapUtil;
import com.cbgolf.oa.util.TypeUtil;
import com.cbgolf.oa.util.Util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;
import org.greenrobot.eventbus.EventBus;

/**
 * 球场巡航统计model
 *
 * @author lq
 * @date 2018/4/27
 */

public class ParkMapModelImp extends BaseModel implements IParkMapModel {

  private final double PLAYER_DIS_1 = 0.00008;
  private final double PLAYER_DIS_2 = 0.00010;
  private final double PLAYER_DIS_3 = 0.00006;
  private final double PLAYER_DIS_4 = 0.00005;
  private final int BUSINESS_NUM = 3;

  @Override
  public void getFirWayLatlon() {
    Web.getOK(WebAPI.park_map_latlon_get, new NetCallBack(response -> {
      EventBus.getDefault().post(new EventPark.Builder()
          .setTarget(DataManager.PARK_MAP_LATLON)
          .setParkBean(getBean(response, ParkBean.class))
          .setError(errorMsg, errorCode)
          .build());
    }));
  }

  @Override
  public void requestUserInfo(String userId, int type) {
    Web.getOK(WebAPI.userinfo_select_get + userId, new NetCallBack(response -> {
      EventBus.getDefault().post(new EventPark.Builder()
          .setTarget(DataManager.PARK_MAP_USER_INFO)
          .setParkBean(getBean(response, ParkBean.class))
          .setType(type)
          .setError(errorMsg, errorCode)
          .build());
    }));
  }

  @Override
  public void getStatisticsInfo() {
    Web.getOK(WebAPI.park_details_select_get,
        new NetCallBack(response -> {
          EventBus.getDefault().post(new EventPark.Builder()
              .setTarget(DataManager.PARK_MAP_STATISTICS)
              .setParkBean(getBean(response, ParkBean.class))
              .setError(errorMsg, errorCode)
              .build());
        }));
  }

  @Override
  public void filterCaddieNum(ParkBean bean) {
    if (null == bean || Util.listIsNull(bean.ListParkWayInfoCoverted)
        || Util.listIsNull(bean.listCaddieLatLng)) {
      return;
    }
    List<ParkWayInfo> listBusiness = new ArrayList<>();
    ThreadFactory factory = r -> new Thread(r);
    ExecutorService service = new ThreadPoolExecutor(1, 1, 0L,
        TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024), factory, new AbortPolicy());
    service.execute(() -> {
      List<LatLng> listCaddie = bean.listCaddieLatLng;
      List<ParkWayInfo> listWays = bean.ListParkWayInfoCoverted;
      List<LatLon> listCaddieInfo = bean.listCaddie;
      Map<String, Integer> mapCount = new ArrayMap<>();
      Map<String, Integer> mapTeetimeCount = new ArrayMap<>();
      for (int x = 0; x < listCaddie.size(); x++) {
        for (int i = 0; i < listWays.size(); i++) {
          if (MapUtil.isInRange(listCaddie.get(x),
              listWays.get(i).fairwayPoints)) {
            if (!mapTeetimeCount.containsKey(listCaddieInfo.get(x).teeTimeId)) {
              mapCount.put(listWays.get(i).fairwayName,
                  CollectionUtil.getMapInt(mapCount, listWays.get(i).fairwayName) + 1);
            }
            mapTeetimeCount.put(listCaddieInfo.get(x).teeTimeId,
                CollectionUtil.getMapInt(mapTeetimeCount, listCaddieInfo.get(x).teeTimeId) + 1);
            break;
          }
        }
      }
      if (!CollectionUtil.mapIsNull(mapCount)) {
        ParkWayInfo bean1;
        for (Map.Entry<String, Integer> me : mapCount.entrySet()) {
          for (int i = 0; i < listWays.size(); i++) {
            if (Util.isEquals(me.getKey(), listWays.get(i).fairwayName) &&
                TypeUtil.getInt(me.getValue()) >= BUSINESS_NUM) {
              bean1 = new ParkWayInfo();
              bean1.caddieNum = me.getValue();
              bean1.fairwayName = me.getKey();
              bean1.fairwayPoints = listWays.get(i).fairwayPoints;
              bean1.isBussiness = true;
              listBusiness.add(bean1);
            }
          }
        }
      }
      EventBus.getDefault().post(new EventPark.Builder()
          .setTarget(DataManager.PARK_MAP_FILTER_BUSSINESS)
          .setListBussinessWays(listBusiness)
          .build());
    });
    service.shutdown();
  }

  @Override
  public void filterId(List<LatLon> list) {
    if (Util.listIsNull(list)) {
      EventBus.getDefault().post(new EventPark.Builder()
          .setTarget(DataManager.PARK_MAP_UPDATE_CADDIE_PLAYER_WORKER_LOCATION)
          .setParkBean(new ParkBean.Builder()
              .setInParkPlayerNum(0)
              .build())
          .build());
      return;
    }
    List<LatLon> listCaddie = new ArrayList<>();
    List<LatLon> listPlayer = new ArrayList<>();
    List<LatLon> listWorker = new ArrayList<>();
    List<LatLng> listCaddieLatLng = new ArrayList<>();
    List<LatLng> listPlayerLatLng = new ArrayList<>();
    List<LatLng> listWorkerLatLng = new ArrayList<>();
    ThreadFactory factory = r -> new Thread(r);
    ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<>(1024),
        factory, new ThreadPoolExecutor.AbortPolicy());
    singleThreadPool.execute(() -> {
      for (int i = 0; i < list.size(); i++) {
        if (Util.isEquals(list.get(i).identityType, "CADDIE")) {
          listCaddie.add(list.get(i));
          listCaddieLatLng.add(new LatLng(TypeUtil.parseDauble(list.get(i).lat),
              TypeUtil.parseDauble(list.get(i).lng)));
        } else if (Util.isEquals(list.get(i).identityType, "PERSONNEL")) {
          listWorker.add(list.get(i));
          listWorkerLatLng.add(new LatLng(TypeUtil.parseDauble(list.get(i).lat),
              TypeUtil.parseDauble(list.get(i).lng)));
        }
      }
      int inParkPersonNum = 0;
      if (!Util.listIsNull(listCaddie)) {
        for (int i = 0; i < listCaddie.size(); i++) {
          listPlayer.add(listCaddie.get(i));
          int num = TypeUtil.getInt(listCaddie.get(i).customerCount);
          inParkPersonNum += (num + 1);
          if (num > 0) {
            double lat;
            double lng;
            for (int j = 0; j < num; j++) {
              switch (j % 4) {
                case 0:
                  lat = TypeUtil.parseDauble(list.get(i).lat);
                  lng = TypeUtil.parseDauble(list.get(i).lng) - PLAYER_DIS_1;
                  break;
                case 1:
                  lat = TypeUtil.parseDauble(list.get(i).lat) + PLAYER_DIS_2;
                  lng = TypeUtil.parseDauble(list.get(i).lng);
                  break;
                case 2:
                  lat = TypeUtil.parseDauble(list.get(i).lat);
                  lng = TypeUtil.parseDauble(list.get(i).lng) + PLAYER_DIS_3;
                  break;
                case 3:
                  lat = TypeUtil.parseDauble(list.get(i).lat) - PLAYER_DIS_4;
                  lng = TypeUtil.parseDauble(list.get(i).lng);
                  break;
                default:
                  lat = TypeUtil.parseDauble(list.get(i).lat);
                  lng = TypeUtil.parseDauble(list.get(i).lng);
                  break;
              }
              listPlayerLatLng.add(new LatLng(lat, lng));
            }
          }
        }
      }
      EventBus.getDefault().post(new EventPark.Builder()
          .setTarget(DataManager.PARK_MAP_UPDATE_CADDIE_PLAYER_WORKER_LOCATION)
          .setParkBean(new ParkBean.Builder()
              .setListCaddieInfo(listCaddie)
              .setListCaddieLatlng(listCaddieLatLng)
              .setListWorderInfo(listWorker)
              .setListWorderLatlng(listWorkerLatLng)
              .setListPlayerInfo(listPlayer)
              .setListPlayerLatlng(listPlayerLatLng)
              .setInParkPlayerNum(inParkPersonNum)
              .build())
          .build());
    });
    singleThreadPool.shutdown();
  }

  @Override
  public void filterCaddieWorking(ParkBean bean) {
    ThreadFactory factory = r -> new Thread(r);
    ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<>(1024),
        factory, new ThreadPoolExecutor.AbortPolicy());
    singleThreadPool.execute(() -> filterParkRatio(bean));
    singleThreadPool.shutdown();

  }

  private void filterParkRatio(ParkBean bean) {
    int parkWayNum = 0;
    int useWayNum = 0;
    if (null == bean || Util.listIsNull(bean.listCaddieLatLng)
        || Util.listIsNull(bean.ListParkWayInfoCoverted)) {
      backFilterRatio(useWayNum, parkWayNum);
      return;
    }
    List<LatLng> listCaddieLatlng = new ArrayList<>();
    listCaddieLatlng.addAll(bean.listCaddieLatLng);
    List<ParkWayInfo> listAllInfo = new ArrayList<>();
    listAllInfo.addAll(bean.ListParkWayInfoCoverted);
    parkWayNum = listAllInfo.size();
    for (int i = 0; i < listCaddieLatlng.size(); i++) {
      if (Util.listIsNull(listAllInfo)) {
        break;
      }
      for (int j = 0; j < listAllInfo.size(); j++) {
        if (MapUtil.isInRange(listCaddieLatlng.get(i), listAllInfo.get(j).fairwayPoints)) {
          useWayNum++;
          listAllInfo.remove(j);
          break;
        }
      }
    }
    backFilterRatio(useWayNum, parkWayNum);
  }


  private void backFilterRatio(int useWayNum, int parkWayNum) {
    EventBus.getDefault().post(new EventPark.Builder()
        .setTarget(DataManager.STATISTICS_PLAYER_PARKWAY_RATIO)
        .setCompare(0 != useWayNum && 0 != parkWayNum ?
            new StringBuilder()
                .append(useWayNum)
                .append("/")
                .append(parkWayNum)
                .toString()
            : "0")
        .build());
  }
}
